import * as ol from "ol";
import VectorLayer from "ol/layer/Vector";
import { Point } from "ol/geom";
import { MapUtils } from "./MapUtils"; // 地图工具类
import { MapOptions, OlCzmlConfig, MarkerOptions } from "../types/MapOptions"; // 地图配置项
import { loadTileLayer } from "./TileLayerManager";  // tile瓦片处理类
import LayerManager from "../core/LayerManager"; // 图层处理类
import { FileManager, GeometryManager, OlMarker_Manager, GeoJson_bordLine_annotationManager, MouseEventHandler } from "../core/layerDataManager"; // 数据处理类
import { layers } from "../mapConfig/layerConfig";
import { CustomPopup } from "./Overlay";  // 弹窗处理类
import { TimeLineManager } from "./TimeLineManager"; // 时间轴处理类
import { eventBus } from './EventBus'; // 事件总线
import { SafeShootingRealm } from "./SafeShootingRealm"; // 安全射击域
import { ModelManager, FlightDataReceiver } from './realTime' // 实时数据接收类
import { Feature } from "ol";
import { fromLonLat } from "ol/proj";
import { getAssets } from "../../../utils";
let animationFrameId: number | null = null;
let that: this | null = null


export class MapManager {
  private map: ol.Map | undefined
  private mapLayer: LayerManager | undefined  // 地图主处理器
  public timeLine: TimeLineManager | undefined    // 时间轴处理器
  private markManager: OlMarker_Manager | undefined  // 标记点处理类
  private cleanupEvents: (() => void)[] = [];   // 为了方便管理事件，用于存储事件函数
  private customPopup: CustomPopup | undefined; // 自定义弹窗
  static instance: any;
  private currentModel: any;
  constructor() {
  }

  // 获取单实例的静态方法
  public static getInstance(): MapManager {
    if (!MapManager.instance) {
      MapManager.instance = new MapManager()

    }
    return MapManager.instance
  }



  // 初始化地图
  public async initMap(options: MapOptions) {
    this.map = new ol.Map({
      target: options.containerId,
      layers: options.baseLayer,
      view: new ol.View({
        center: MapUtils.lonLatToMapCoord(options.center[0], options.center[1]),
        zoom: options.zoom,
        projection: 'EPSG:3857'
      }),
      controls: []
    })
    this.markManager = new OlMarker_Manager(this.map) // 初始化标记点管理类
    this.mapLayer = new LayerManager(this.map)   // 实例化layer管理层
    // this.timeLine = new TimeLineManager({})   // 初始化时间轴


    // 执行此类的函数
    this.loadTile('initLayer2', layers[1]?.url, true)   // 加载瓦片地图
    this.setGlobeProperty()   // 设置全局变量

    // this.drawSafeShootingRealm()
    this.bindEvents()   // 事件处理函数

    this.customPopup = new CustomPopup(); // 自定义弹窗
    this.timeLine = new TimeLineManager() // 回放
    this.subscriptionInformation()  // 订阅信息
    that = this

  }

  // 加载瓦片图层
  public loadTile(id: string, url: string | undefined, isAllowDelete: boolean = true): void {
    const layer = loadTileLayer(url)   // 获取图层
    this.mapLayer?.addLayer(layer, id, isAllowDelete)  // 添加图层
  }

  // 获取解析csv数据
  public async getAnalysisCSV(url: string) {
    return await FileManager.analysisCSV(url)
  }

  // 获取地图实例
  public getMap(): ol.Map {
    return this.map as ol.Map;
  }

  // 返回初始位置
  goHome() {
    this.setView([126.1722017295496, 43.7084630627787], 7.24, 2)
  }

  // 设置地图视图
  public setView(center: [number, number], zoom?: number, duration?: number): void {
    this.map?.getView().animate({
      center: MapUtils.lonLatToMapCoord(center[0], center[1]),
      duration: duration ? duration : 1,    // 默认动画时常为1秒
      zoom: zoom ? zoom : this.map.getView().getZoom()   // 默认为当前层级
    })
  }

  // 设置缩放级别
  public setZoom(zoom: number): void {
    this.map?.getView().setZoom(zoom);
  }

  // 创建发光闪烁点，并将其添加到地图  (开发未完成)
  public addGlowingPoint(layerId: string, coordinates: [number, number], isAllowDelete: boolean = true) {
    const layer = GeometryManager.createGlowingPoint(MapUtils.lonLatToMapCoord(coordinates[0], coordinates[1]))
    this.mapLayer?.addLayer(layer, layerId, isAllowDelete)

    this.roamToLocation(coordinates[0], coordinates[1])
  }

  // 漫游到指定位置的函数
  public roamToLocation(lon: number, lat: number, zoom: number = 10, duration: number = 1000): void {
    const newCenter = MapUtils.lonLatToMapCoord(lon, lat);
    const view = this.map?.getView();

    // 使用动画平滑过渡到目标位置
    view?.animate({
      center: newCenter,
      zoom: zoom,
      duration: duration
    });
  }

  public mouseFocu() {
    if (this.currentModel) {

      const focusing = [{
        id: 'focusing',
        name: '',
        coordinates: this.currentModel.coordinates,
        data: {},
        image: getAssets(`images/model/focu.png`)
      }]
      this.updateMark('focusing', focusing)
    }

  }
  // 跟踪目标
  public trackTheTarget(id: string) {
  }

  // 放大/缩小图层  'zoom-in' 'zoom-out'
  public zoomInOrOutLayer(zoomType: string) {
    let zoomLevel = this.map?.getView().getZoom();
    if (zoomType == 'zoom-in' && zoomLevel) {
      this.setZoom(zoomLevel + 1)
    } else {
      if (zoomLevel)
        this.setZoom(zoomLevel - 1)
    }
  }


  // 批量添加标点（带图片）
  public addMarks(layerId: string, markData: Array<MarkerOptions>, isAllowDelete: boolean = true) {
    const layer = this.markManager?.addMarkers(markData)
    this.mapLayer?.addLayer(layer, layerId, isAllowDelete)
  }

  public updateMark(layerId: string, markData: Array<MarkerOptions>) {
    // 创建标记点数组
    const markerFeatures = markData.map(data => {
      return new Feature({
        geometry: new Point(MapUtils.lonLatToMapCoord(data.coordinates[0], data.coordinates[1])),
        properties: {
          id: data.id,
          name: '',
          image: data.image,
          data: data.data, // data用于存储额外信息
        },
      });
    });

    // 更新图层，传递整个标记点数组
    this.mapLayer?.updateLayer(layerId, markerFeatures)
  }



  // 设置图层是否可查看
  public setLayerVisble(layerId: string, isShow: boolean) {
    this.mapLayer?.setVisble(isShow, layerId)
  }

  // 清除图层
  public clearLayer(layerId: string) {
    this.mapLayer?.removeLayer(layerId)
  }

  // 移除所有图层
  public clearAllLayer() {
    this.mapLayer?.removeAllLayer();
  }

  // 添加边界线
  public addGeoJson_bordLine(layerId: string, data: any, isAllowDelete = false) {
    const layer = GeoJson_bordLine_annotationManager.createBoundaryLayer(data['features'])
    this.mapLayer?.addLayer(layer, layerId, isAllowDelete)
  }

  // 添加注记
  public addGeoJson_note(layerId: string, data: any, isAllowDelete = false) {
    const layer = GeoJson_bordLine_annotationManager.createLabelLayer(data['features'])
    this.mapLayer?.addLayer(layer, layerId, isAllowDelete)
  }

  // 添加安全射界
  public addSafeShootingRealm(data: Array<{ id: string, center: [number, number], isAllowDelete: boolean, basicsData: Array<any>, shootingRealmData: Array<any> }>) {
    let layer: { id: string; data: VectorLayer | undefined; isAllowDelete: boolean; }[] = []
    data.forEach(item => {
      const shootingRealmArray = SafeShootingRealm.initShootingRealm(item.basicsData, item.center, item.shootingRealmData)
      layer.push({ id: item.id, data: shootingRealmArray, isAllowDelete: item.isAllowDelete })
    })
    if (layer.length > 0) {
      layer.forEach(item => {
        item.data?.setZIndex(50)
        this.mapLayer?.addLayer(item.data, item.id, item.isAllowDelete)
      })
    }

  }


  // 绑定事件
  private bindEvents(): void {
    // 绑定点击事件
    const cleanupClick = MouseEventHandler.bindClickEvent((window as any).olMap.map, (event: any) => {
      // 获取要素
      const features = this.map?.getFeaturesAtPixel(event.pixel);

      if (features && features.length > 0) {
        features.forEach((feature) => {
          const geometry = feature.getGeometry();

          // 判断几何类型是否为 Point
          if (geometry instanceof Point) {
            // 获取点的坐标
            const coordinate = MapUtils.mapCoordToLonLat(event.coordinate);

            // 获取点的属性
            const properties = feature.getProperties();
            const propValue = properties.features[0].getProperties().properties

            // 调用自定义弹出框处理点击事件
            // this.customPopup?.handleMapClick(event);

            // 调整视图位置
            this.roamToLocation(coordinate[0], coordinate[1]);

            // 触发自定义事件，传递经纬度
            eventBus.dispatchEvent('mapClick', {
              lon: coordinate[0],
              lat: coordinate[1],
              properties: propValue // 传递属性信息
            });
          }
        });
      } else {
        console.log('没有找到要素');
      }

      // 清理事件函数（如果需要清理）
      // this.cleanupEvents.push(cleanupClick);
    });

    // // 绑定鼠标移动事件
    // const cleanupMove = MouseEventHandler.bindMoveEvent((window as any).olMap.map, (coordinate: any) => {
    //     // console.log('鼠标当前位置:', coordinate);
    // });
    // this.cleanupEvents.push(cleanupMove);

    // // 绑定缩放事件
    const cleanupZoom = MouseEventHandler.bindZoomEvent((window as any).olMap.map, (zoom: any) => {
      console.log('当前缩放级别:', zoom);
    });
    // this.cleanupEvents.push(cleanupZoom);

  }

  // 初始化回放
  public initializePlayback(czml: OlCzmlConfig) {
    this.timeLine?.init(czml)
  }

  // 回放移动
  public playBackMove(currentTime: number) {
    this.timeLine?.dataCorrespondingToTheTimeFrame(currentTime)
  }

  public clearPlayback(id:string) {
     this.timeLine?.clearModelById(id)
  }
  // 初始化实时数据
  public initRealTimeData(modelData: any) {
    ModelManager.addModel(modelData)
  }

  // 实时数据移动
  public realTimeDataMove(modelData: any) {
    FlightDataReceiver.receiveFlightData(modelData)
    setTimeout(() => {
      // this.animate()
    }, 1500);

  }

  // 清除实时的某个模型
  public clearRealTimeModel(id: string) {
    ModelManager.clearModelById(id) // 清除对应的点
    ModelManager.clearModelById(id + '_line') // 清除对应的线
  }


  public animate() {
    that.updatePlanePosition();
    animationFrameId = requestAnimationFrame(that.animate); // 返回 ID
  }
  public updatePlanePosition() {
    if (this.currentModel) {
      this.map?.getView().animate({
        center: MapUtils.lonLatToMapCoord(this.currentModel.coordinates[0], this.currentModel.coordinates[1])
      })
    }
  }

  public stopAnimate() {
    if (animationFrameId) {
      cancelAnimationFrame(animationFrameId); // 取消动画
    }
  }
  public subscriptionInformation() {
    // 订阅事件
    eventBus.subscribe('dispatchFlightData', (event: any) => {
      // console.log('收到事件:', event.detail);
      this.currentModel = event.detail
      this.mouseFocu()
    });
  }

  public showOverLay(content: any, coordinate: [number, number]) {
    this.customPopup?.setPopupContent(content)
    this.customPopup?.showPopup(coordinate)
  }


  // 销毁时清理事件监听器
  public destroy(): void {
    // 清除所有事件监听
    this.cleanupEvents.forEach(cleanup => cleanup());
    this.cleanupEvents = [];
    console.log('所有事件监听器已被清除');
  }

  // 设置全局变量
  public setGlobeProperty() {
    (window as any).olMap = {
      map: this.map,
      layerManager: this.mapLayer
    };
  }


}
